package org.euitio.jmplayer.controller;

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.euitio.jmplayer.model.PositionChangedEvent;

public class MPlayer {

    private static MPlayer INSTANCE = null;
    private MPlayerReaderThread reader;
    private Process mplayer;
    private BufferedWriter writer;
    private ArrayList<PositionChangedListener> _positionChangedListeners;
    private Timer timer;

    private MPlayer() {
        try {
            _positionChangedListeners = new ArrayList<PositionChangedListener>();            
            mplayer = Runtime.getRuntime().exec("c:\\mplayer.exe -slave -quiet -idle");
            reader = new MPlayerReaderThread(mplayer.getInputStream());
            new Thread(reader).start();
            writer = new BufferedWriter(new OutputStreamWriter(mplayer.getOutputStream()));
        } catch (IOException ex) {
            Logger.getLogger(MPlayer.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    /**
     * Implemented because this object is Singelton
     * @return The instance of the class
     */
    public static MPlayer getInstance() {
        if (INSTANCE == null) {
            INSTANCE = new MPlayer();
        }
        return INSTANCE;
    }

    public void subscribeToPositionChangeEvents(PositionChangedListener listener) {
        if (!_positionChangedListeners.contains(listener)) {
            _positionChangedListeners.add(listener);
        }
    }

    public void unsubscribeToPositionChangeEvents(PositionChangedListener listener) {
        if (_positionChangedListeners.contains(listener)) {
            _positionChangedListeners.remove(listener);
        }
    }

    void updatePositionChangeListeners(int newPercent) {
        PositionChangedEvent event = new PositionChangedEvent(this, newPercent);
        if(newPercent == 100)
            timer.cancel();
        for (PositionChangedListener listener : _positionChangedListeners) {
            listener.positionChanged(event);
        }
    }

    /**
     * This method will play an audio file
     * @param path
     */
    public void loadFile(String path) {
        if (System.getProperty("os.name").toLowerCase().startsWith("win")) {
            path = path.replace('\\', '/');
        }
        sendCommand("loadfile " + path + " 0");
        timer = new Timer();
        timer.scheduleAtFixedRate(getPercentTask, 0, 1000);
    }

    public void closePlayer() {
        sendCommand("quit");
        mplayer.destroy();
    }

    private void sendCommand(String command) {
        try {
            writer.write(command + '\n');
            writer.flush();
        } catch (IOException ex) {
            Logger.getLogger(MPlayer.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    TimerTask getPercentTask = new TimerTask() {

        @Override
        public void run() {
            sendCommand("get_percent_pos");
        }
    };
}
